﻿using System.Text;
using System.Windows;
using Syncfusion.Windows.Tools.Controls;
using System.Windows.Data;
using Common.Client.Lib.Extensions;
using Common.Client.Lib.Model;
using Common.Lib;
using Common.Lib.Localization;
using Common.Mvvm.Navigation;
using Common.Mvvm.Navigation.Regions;
using Syncfusion.Lib.Data;
using Syncfusion.Lib.ViewModels;

namespace Syncfusion.Lib.Extensions
{
    /// <summary>
    /// Prism Region 扩展，主要搭配SfDocking MVVM模式使用
    /// </summary>
    public static class SfDockingManagerExtension
    {
        /// <summary>
        /// 主窗体Region标识
        /// </summary>
        public static readonly string MainWindowRegionIdentify = "MainWindowRegionIdentify";

        public static readonly IRegionManager RegionManager = new RegionManager().CreateRegionManager();

        /// <summary>
        /// 实现 <see cref="ISfDockingManager"/> VM的字典
        /// </summary>
        public static Dictionary<string, ISfDockingManager> SfDockingManagerViewModelDictionary = new Dictionary<string, ISfDockingManager>();

        private static readonly object Lock = new object();

        /// <summary>
        /// 注册 SfDockingManagerViewModel 
        /// </summary>
        /// <param name="key">ISfDockingManagerViewModel存储的Key值</param>
        /// <param name="sfDockingManagerViewModel"></param>
        /// <returns></returns>
        public static void RegisterSfDockingManagerViewModel(string key, ISfDockingManager sfDockingManagerViewModel)
        {
            lock (Lock)
            {
                if(!SfDockingManagerViewModelDictionary.ContainsKey(key))
                {
                    lock(Lock)
                    {
                        if(!SfDockingManagerViewModelDictionary.ContainsKey(key))
                        {
                            sfDockingManagerViewModel.SfDockingInfo = new SfDockingInfo();
                            Region documentRegion = new Region
                            {
                                Name = $"SfDockingManagerRegion_{key}",
                                RegionManager = RegionManager
                            };
                            RegionManager.Regions.Add(documentRegion);
                            sfDockingManagerViewModel.SfDockingInfo.Region = documentRegion;
                            SfDockingManagerViewModelDictionary.Add(key, sfDockingManagerViewModel);
                            Common.Mvvm.Navigation.Regions.RegionManager.UpdateRegions();
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 取消注册MainWindowModel
        /// </summary>
        /// <param name="sfDockingManagerViewModelKey">ISfDockingManagerViewModel存储的Key值</param>
        /// <returns></returns>
        public static void UnRegisterMainWindowViewModel(string sfDockingManagerViewModelKey)
        {
            lock (Lock)
            {
                if (SfDockingManagerViewModelDictionary.ContainsKey(sfDockingManagerViewModelKey))
                {
                    lock (Lock)
                    {
                        // ReSharper disable once CanSimplifyDictionaryRemovingWithSingleCall
                        if (SfDockingManagerViewModelDictionary.ContainsKey(sfDockingManagerViewModelKey))
                        {
                            SfDockingManagerViewModelDictionary.Remove(sfDockingManagerViewModelKey);
                        }
                    }
                }
            }
        }


        /// <summary>
        /// 获取MainWindowModel
        /// </summary>
        /// <param name="sfDockingManagerViewModelKey">ISfDockingManagerViewModel存储的Key值</param>
        /// <returns>不存在返回 null </returns>
        public static ISfDockingManager? GetSfDockingManagerViewModel(string sfDockingManagerViewModelKey)
        {
            ISfDockingManager? res = null;
            lock (Lock)
            {
                if (!SfDockingManagerViewModelDictionary.TryGetValue(sfDockingManagerViewModelKey, out var value))
                {
                    lock (Lock)
                    {
                        if (SfDockingManagerViewModelDictionary.TryGetValue(sfDockingManagerViewModelKey, out var value1))
                        {
                            res = value1;
                        }
                    }
                }
                else
                {
                    res = value;
                }
            }
            return res;
        }

        /// <summary>
        /// 判定加载指定功能，当DockingManagerContent已加载，则激活对应的DockingManagerContent
        /// </summary>
        /// <param name="sfDockingManagerViewModelKey"></param>
        /// <param name="function">功能列表</param>
        /// <returns></returns>
        public static IReturnResultInfo JudgeLoadDockingManagerContent(string sfDockingManagerViewModelKey,FunctionModel function)
        {
            ISfDockingManager? vm = GetSfDockingManagerViewModel(sfDockingManagerViewModelKey);
            return JudeLoadRegionDockingManagerContent(function, vm?.SfDockingInfo);
        }


        /// <summary>
        /// 判定关闭指定的DockingManagerContent
        /// </summary>
        /// <param name="sfDockingManagerViewModelKey"></param>
        /// <param name="fe">功能元素</param>
        /// <returns></returns>
        public static IReturnResultInfo JudgeCloseDockingManagerContent(string sfDockingManagerViewModelKey, FrameworkElement fe)
        {
            IReturnResultInfo res = new LocalizationReturnResultInfo();
            ISfDockingManager? vm = GetSfDockingManagerViewModel(sfDockingManagerViewModelKey);
            IRegion? region = vm?.SfDockingInfo.Region;
            if (region != null && region.Views.Contains(fe))
            {
                region.Remove(fe);                
            }
            res.Succeed = true;
            return res;
        }

        /// <summary>
        /// 判定加载指定VM的DockItem,当指定的 function 存在时，激活相应的功能
        /// </summary>
        /// <param name="sfDockingInfo"></param>
        /// <param name="function"></param>
        /// <returns></returns>
        private static IReturnResultInfo JudeLoadRegionDockingManagerContent(
            FunctionModel function,
            SfDockingInfo? sfDockingInfo)
        {
            IReturnResultInfo res = new LocalizationReturnResultInfo();
            //判断功能菜单是否已加载
            try
            {
                if (string.IsNullOrEmpty(function.FunctionAddress))
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine($"功能菜单导航地址为空，请查证：");
                    sb.AppendLine($"{nameof(function.Id)} = {function.Id}");
                    sb.AppendLine($"{nameof(function.Code)} = {function.Code}");
                    sb.AppendLine($"{nameof(function.Caption)} = {function.Caption}");
                    sb.AppendLine($"{nameof(function.Name)} = {function.Name}");
                    sb.AppendLine($"{nameof(function.AsName)} = {function.AsName}");
                    res.Message = sb.ToString();
                    return res;
                }

                IRegion? region = sfDockingInfo?.Region;
                if (region == null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine($"功能菜单导航区域未注册，请查证！");
                    res.Message = sb.ToString();
                    return res;
                }
                //调用Region导航实例，获取VM
                region.RequestNavigate(
                    function.FunctionAddress,
                    (res) =>
                    {

                    },
                    new NavigationParameters()
                    {
                        {NavigationParameterExtension.SysFunctionParameter,function.FunctionParam ?? ""},
                        {NavigationParameterExtension.SysFunctionTitle,function.Name ?? ""},
                        {NavigationParameterExtension.SysFunctionIcon,function.Icon ?? ""},
                    });
                var targetView = region.Views.FirstOrDefault(p => p?.GetType()?.AssemblyFullName() == function.FunctionAddress);
                if(targetView == null)
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine($"功能菜单导航地址未注册，请查证：");
                    sb.AppendLine($"{nameof(function.Id)} = {function.Id}");
                    sb.AppendLine($"{nameof(function.Code)} = {function.Code}");
                    sb.AppendLine($"{nameof(function.Caption)} = {function.Caption}");
                    sb.AppendLine($"{nameof(function.Name)} = {function.Name}");
                    sb.AppendLine($"{nameof(function.AsName)} = {function.AsName}");
                    sb.AppendLine($"{nameof(function.FunctionAddress)} = {function.FunctionAddress}");
                    res.Message = sb.ToString();
                    return res;
                }
                region.Activate(targetView);
                if (targetView is FrameworkElement fe)
                {
                    if(fe.DataContext is ISfDockingManagerNavigationAware sfdmna)
                    {
                        sfdmna.ContentProperty.Function = function;
                        //通过Binding设置功能名称
                        Binding bindingHeader = new Binding("ContentProperty.Function.Name");
                        bindingHeader.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
                        bindingHeader.TargetNullValue = function.Name;
                        BindingOperations.SetBinding(fe, DocumentContainer.HeaderProperty, bindingHeader);
                        BindingOperations.SetBinding(fe, DocumentContainer.TabCaptionToolTipProperty, bindingHeader);
                    }
                    else
                    {
                        fe.SetValue(DocumentContainer.HeaderProperty, function.Name);
                        fe.SetValue(DocumentContainer.TabCaptionToolTipProperty, function.Name);
                    }

                    if (sfDockingInfo != null)
                    {
                        sfDockingInfo.ActiveWindow = fe;
                    }
                    res.Succeed = true;
                }
                else
                {
                    res.Message = LocalizationResource.GetResourceValue($"打开功能菜单失败，未获取到功能值");
                }
            }
            catch (Exception ex)
            {
                res.Message = LocalizationResource.StringFormat(
                    "打开功能菜单失败，\r\n{0}", 
                    isConverterArgs:false,
                    args: [ex.Output()]);
                res.Info = $"打开功能菜单失败，\r\n入参：\r\n{function.JsonSerialize()}\r\n{ex.DetailInfo()}";
            }
            return res;
        }

        /// <summary>
        /// 设置SfDockingManager相关的依赖属性
        /// </summary>
        public static void SetSfDockingManagerDependencyProperty(FrameworkElement fe)
        {
            //sf:DocumentContainer.AllowPin="False"
            //sf:DocumentContainer.Header="{Binding ContentProperty.Function.Name}"
            //sf:DocumentContainer.IsPinned="True"
            //sf:DocumentContainer.ShowPin="False"
            fe.SetValue(DocumentContainer.AllowPinProperty, true);
            fe.SetValue(DocumentContainer.IsPinnedProperty, false);
            fe.SetValue(DocumentContainer.ShowPinProperty, true);
            fe.SetValue(DocumentContainer.CanCloseProperty, true);
            fe.SetValue(DocumentContainer.CanDragProperty, true);
            fe.SetValue(DockingManager.AutoHideVisibilityProperty, true);
            fe.SetValue(DockingManager.StateProperty, DockState.Document);
            fe.SetValue(DockingManager.ShowFloatWindowInTaskbarProperty, true);
            fe.SetValue(DockingManager.ShowInTaskbarProperty, true);

            fe.SetValue(DockingManager.CanAutoHideProperty, true);
            fe.SetValue(DockingManager.CanMinimizeProperty, false);
            fe.SetValue(DockingManager.CanMinimizeFloatProperty, false);
            //fe.SetValue(DockingManager.SizetoContentInDockProperty, true);
            //fe.SetValue(DockingManager.SizetoContentInFloatProperty, true);
            fe.SetValue(DockingManager.CanMaximizeProperty, true);
        }
    }
}
